iT邦幫忙

2025 iThome 鐵人賽

DAY 17
0

https://ithelp.ithome.com.tw/upload/images/20250831/20118113BLkCodRJyL.png

除錯 - Tap

在函數式程式設計風格中,資料的串接通常利用pipe、flow或compose將函數式合成,因此程式開發人員比較難在「接管」(pipe)過程中觀察各個函數輸出的結果,一旦程式出現邏輯上的錯誤時,較難偵錯。

我們在介紹pipe、flow和compose的時候,介紹了trace這個函數,我們可任意將它安置在pipe中任一個函數之後,以觀察該函數輸出結果來協助偵錯,了解程式的邏輯問題。

const trace =
  (label?: string) =>
  <A>(a: A) => {
    console.log(label ? `${label}:` : 'trace:', a);
  };

當函數輸出的型別是一般型別,trace函數可以將值直接log在Console中,當輸出結果為Option或Either建構的型別時,Console中出現的不是單純我們所想觀察的值,會是Option和Either建構出來的物件,我們必須從物件中找出正確屬性的值,雖然較麻煩,但還是能看到函數輸出的值。
如果我們函數的輸出型別是IO和Task時,這個容器建構出來的是尚未執行的函數,上面的trace函數就無用武之地。我們可以修改上面的trace函數,讓我們知道IO型別和Task型別執行的結果,從中理解程式邏輯錯誤的原因。

const traceIO =
  <A>(label?: string) =>
  (fa: IO<A>): IO<A> => {
    console.log(label ? `${label}:` : 'trace:', fa());
    return fa;
  };

tap

除了自行設計trace函數,我們也可以使用各個模組提供的tap或其它tap相關的函數來協助我們除錯,下面我們就來介紹各個tap函數及其相關函數的使用方法。假設F是一個型別建構子,tap函數第一個參數是一個函數f,而f是一個A => F<A>的函數,tap的第二個參數是F<A>型別,tap最後會回傳型別F<A>的結果。以Option.tap的型別簽名為例:

tap: <A>(f: (a: A) => Option<any>) => (self: Option<A>) => Option<A>

tap執行邏輯如下:

  • 當self為none時,跳過f,tap直接回傳none。
  • 當self不是none時,執行f
    • 如果f回傳none,則tap也回傳none
    • 如果f回傳不是none,則tap回傳self
      基本上tap是吃什麼就吐什麼,它的行為和trace很類似,輸入和輸出一樣,放在pipe的各函數之間,通常不會影響輸出的結果。tap(f)可以依self的值調整輸出的型別,選擇屏蔽一些輸出,更具彈性的包裝我們的f。通常f會執行一有Side effct的程式碼,以便進行偵錯。f的回傳值沒有意義,但是回傳的型別是some或none會影響是否原值輸出還是輸出none。

tapEither的基本行為和tap一樣,不同的是tapEither中f的輸出型別為Either,如果f輸出right則tapEither輸出some,f輸出left則tapEither輸出none。
下列程式碼你可以進行測試和練習。

import * as O from 'fp-ts/Option';
import * as E from 'fp-ts/Either';
import { pipe } from 'fp-ts/function';
const tapOption: string = pipe(
  some(2),
  O.tapEither((x) => {
    console.log(`Value is ${x}`);
    if (x > 30) return E.right('son');
    return E.left(0);
  }),
  O.match(
    () => 'none',
    (v) => String(v)
  )
);

今日小結

各個模組中的tap函數的邏輯都是相似,IO和Task因為沒有失敗的情形,只要輸出型別正確,f執行之後,會把原輸入直接輸出,這個f通常是一些Side effect,協助偵錯用。tap另外有一個別名(alias),稱之為chainFirst,使用邏輯一樣,掌握了tap函數的用法,可以讓你的偵錯過程更為順利。今天的分享內容就到這邊,明天再見。


上一篇
Day 16. 非同步工作 - Task & TaskEither
下一篇
Day 18. 自然轉換 - Natural Transformation
系列文
數學老師學函數式程式設計 - 以fp-ts啟航20
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言